<?php
/**
 * CreateTime: 2022/6/1 11:38
 */

namespace App\Http\Controllers;

use App\Consts\Approval\ApprovalSubmitTypeConsts;
use App\Consts\DingTalkConsts\DingTalkConfigConsts;
use App\Func\AppFunc;
use App\Models\Approval\OldDingTalkApprovalModel;
use App\Models\DingTalk\DingTalkApprovalProcessModel;
use App\Service\Approval\OldDingTalkApprovalService;
use App\Tools\DingTalk\DingCallbackCrypto;
use App\Tools\DingTalk\DingTalkCallBackFacade;
use App\Tools\DingTalk\DingtalkCrypt;
use App\Tools\Log\Log;
use Illuminate\Support\Facades\App;
use Mockery\Exception;

class DingTalkRollBackController
{

    public function regiserCallBackI(){
        dd(DingTalkCallBackFacade::registerCallBack());
    }

    public function regiserCallBackO(){
         dd(DingTalkCallBackFacade::deleteRegisterCallBack());
    }




    public function triggerDingTalkRollBackEvent(){
        $data = request()->all();
        $SUITE_KEY = AppFunc::getDingTalkConfig()::DING_TALK_CORP_ID;
        $TOKEN = AppFunc::getDingTalkConfig()::DINT_TALK_EVENT_TOKEN;
        $ENCODING_AES_KEY = AppFunc::getDingTalkConfig()::DINT_TALK_EVENT_ENCODING_AES_KEY;
        $signature = $data["signature"];
        $timeStamp = $data["timestamp"];
        $nonce = $data["nonce"];
        $postdata = file_get_contents("php://input");
        $postList = json_decode($postdata, true);
        $encryptMsg = $postList['encrypt'];
        $crypt = new DingtalkCrypt($TOKEN, $ENCODING_AES_KEY, AppFunc::getDingTalkConfig()::DING_TALK_APP_KEY);

        $decryptMsg = "";
        $decryptMsgData = $crypt->DecryptMsg($signature, $timeStamp, $nonce, $encryptMsg, $decryptMsg);
        Log::e($decryptMsg);
        $eventJson = json_decode($decryptMsg,true);
        $eventType  = $eventJson['EventType'];

        if ($decryptMsgData['ErrorCode'] != 0) {//当解密失败记录
            Log::e("ErrorCode:" . $decryptMsgData['ErrorCode']);
        } else {
            if (!$decryptMsgData['data']) {//当返回值为空记录加密字符串信息
                Log::e(json_encode($_GET));
            }
            //创建成功后的回调推送
            $processData = $decryptMsgData['data'];
            Log::e("StartProcessData------------------------------------------------------");
            Log::e($processData);
            Log::e("EndProcessData------------------------------------------------------");
            $processFmtData = json_decode($processData,true);
            $eventType = $processFmtData['EventType'];
            if($eventType != 'check_url'){
                $processId = $processFmtData["processInstanceId"];
                // 如果是bpms_instance_change节点进入开始结束判断
                if($eventType == "bpms_instance_change")
                {
                    $processType = $processFmtData['type'];
                    $processStatus = @$processFmtData['result'];
                    $this->disposeBPMsInstanceChange($processId,$processType,$processStatus);
                }else{
                    $this->disposeBPMsTaskChange($processId,$processData);
                }
            }
        }

        $res = "success";
        $encryptMsg = "";
        try {
            $errCode = $crypt->EncryptMsg($res, $timeStamp, $nonce, $encryptMsg);
            Log::e(json_encode($errCode));
            Log::e("----------------------errCode");
        }catch (\Exception $exception){
            Log::e($exception);
        }
        echo $encryptMsg;
        die();
    }

    /**
     * 回调变动地址
     */
    public function triggerDingTalkRollBack(){
        $data = request()->all();
        # // CorpId: 品帛
//        $SUITE_KEY = "dingce0fdebfd8fcee0cacaaa37764f94726";
        # 物流
        $SUITE_KEY = "dingd8be9d90ee02b21535c2f4657eb6378f";
        $TOKEN = "zkVFMenQboXAG1exuKKygGLCWXLFmV2u1eKL5c";
//        $TOKEN = "Lhk1IA93hKkKNh3mmOzBACp4fonjXie9zjvuKuU53d21Lt";
        $ENCODING_AES_KEY = "w6pjxK7LznA2tma5juMBHDLUgUHJ6PkszAL1QyuVWpO";
//        $ENCODING_AES_KEY = "rjc8RxLtjp6w78HbgXWMAYf4XNcnVsEXzjDYu1cYdub";
        // 获取参数
        $signature = $data["signature"];
        $timeStamp = $data["timestamp"];
        $nonce = $data["nonce"];
        $postdata = file_get_contents("php://input");
        $postList = json_decode($postdata, true);
        $encrypt = $postList['encrypt'];
        $crypt = new DingtalkCrypt($TOKEN, $ENCODING_AES_KEY, $SUITE_KEY);
        $msg = "";
        $res = $crypt->DecryptMsg($signature, $timeStamp, $nonce, $encrypt, $msg);
        Log::e("777777777777777777777777777777777777777");
        if ($res['ErrorCode'] != 0) {//当解密失败记录
            Log::e("ErrorCode:" . $res['ErrorCode']);
            Log::e(json_encode($_GET));
            Log::e(json_encode($encrypt));
            Log::e('------------------------------------------------------------------------------------------');
        } else {
            if (!$res['data']) {//当返回值为空记录加密字符串信息
                Log::e(json_encode($_GET));
                Log::e(json_encode($encrypt));
            }
            //创建成功后的回调推送
            $processData = $res['data'];
            Log::e("StartProcessData------------------------------------------------------");
            Log::e($processData);
            Log::e("EndProcessData------------------------------------------------------");
            $processFmtData = json_decode($processData,true);
            $eventType = $processFmtData['EventType'];
            Log::e($eventType);
            if($eventType != 'check_url'){
                $processId = $processFmtData["processInstanceId"];
                // 如果是bpms_instance_change节点进入开始结束判断
                if($eventType == "bpms_instance_change")
                {
                    $processType = $processFmtData['type'];
                    $processStatus = @$processFmtData['result'];
                    $this->disposeBPMsInstanceChange($processId,$processType,$processStatus);
                }else{
                    $this->disposeBPMsTaskChange($processId,$processData);
                }
            }
        }
        $res = "success";

        $encryptMsg = "";
        try {
            $errCode = $crypt->EncryptMsg($res, $timeStamp, $nonce, $encryptMsg);
            Log::e("----------------------errCode");
        }catch (\Exception $exception){
            Log::e($exception);
        }
//        return $errCode['data'];
        echo $encryptMsg ?? $res;

    }

    public function readDingTalkRollBackLog(){
        return file_get_contents(__DIR__.DIRECTORY_SEPARATOR."1.txt");
    }

    // bpms_task_change是审批节点信息推送，审批发起，结束，中间审批人执行审批的信息都可以获取到
    private function disposeBPMsTaskChange($processInstanceId,$processInfo){
       $od =  new OldDingTalkApprovalService();
       // 检查当前审批ID是否由合同管理系统发起 如果不是则直接跳过
       $ddm = new OldDingTalkApprovalModel();
       $isExists = $ddm->getTalkApprovalInfoByDingTalkApprovalProcessId($processInstanceId,['ding_talk_approval_id']);
       if(!$isExists){
           return "";
       }

       // 审批详情
       $processInfo = $od->getDingTalkApprovalRecode($processInstanceId);
       $data = [
            'operation_records' => json_encode($processInfo['operation_records'],256)
       ];
       if($processInfo['finish_time']){
            $data['finish_time'] = $processInfo['finish_time'];
       }
       // 更新送审实例表
       $om = new OldDingTalkApprovalModel();
       $om->editApproval($processInstanceId,$data);
    }

    /**
     * 处理送审开始结束事件
     * @param $processType
     * @param $processInstanceId
     */
    private function disposeBPMsInstanceChange($processInstanceId,$processType,$processStatus){
        // 获取合同审批信息
        try {
            // 检查当前审批ID是否由合同管理系统发起 如果不是则直接跳过
            $ddm = new OldDingTalkApprovalModel();
            $isExists = $ddm->getTalkApprovalInfoByDingTalkApprovalProcessId($processInstanceId,['ding_talk_approval_id']);
            if(!$isExists){
                return "";
            }

            Log::e("开始结束操作");
            Log::e($processInstanceId);
            $dintTalkApprovalModel = new OldDingTalkApprovalModel();
            $dintTalkApprovalData = $dintTalkApprovalModel->getTalkApprovalInfoByDingTalkApprovalProcessId($processInstanceId,[
                "ding_talk_approval_id",
                "submit_approval_source_id",
                "submit_approval_type",
            ])->toArray();
			
            Log::e("开始结束操作2");
            // 送审类型调用对应的实体
            $subCModel = new ApprovalSubmitTypeConsts();
			
            Log::e("开始结束操作2.0");
			
			# 钉钉审批实例id
            $dingTalkApprovalId = $dintTalkApprovalData['ding_talk_approval_id'];
            # 来源类型
			$submitApprovalSourceId = $dintTalkApprovalData['submit_approval_source_id'];
            $submitApprovalType = $dintTalkApprovalData['submit_approval_type'];

			Log::e("开始结束操作2.1".$dingTalkApprovalId);
			Log::e("开始结束操作2.2".$submitApprovalSourceId);
            $entity = $subCModel->getApprovalEntityByApprovalSubmitTypeConsts($submitApprovalType);
            Log::e("开始结束操作3");
            Log::e($processType);
            Log::e($processStatus);
            Log::e($submitApprovalType);
            switch ($processType){
                case 'start':
                    Log::e("审批开始-------------");
                    $entity->approvalStart($dingTalkApprovalId,$submitApprovalSourceId,$processStatus);
                    break;
                case 'finish':
                    # 正常审批结束
                    if($processStatus == 'agree'){
                        $entity->approvalAgreeEnd($dingTalkApprovalId,$submitApprovalSourceId,$processStatus);
                    }else{
                        Log::e("进入了修改方法");
                        # 拒绝或非正常审批结束
                        $entity->approvalRefuseEnd($dingTalkApprovalId,$submitApprovalSourceId,$processStatus);
                    }
                    break;
                default:
                    break;
            }
        }catch (Exception $exception){
            Log::e($exception->getMessage());
        }
    }


}